/**
* @fileoverview 一个简单js库
 * Created by 2kid.
 * Date: 11-11-4
 * Time: 上午10:33
* @author 2kid
* @version 0.001
*/

(function() {
    var win = window,doc = window['document'];
    /**
     * @name F
     * @object
     * @namespace
     * 名称空间默认Fky，如果没有定义F，也可以用F
     * Fky库的核心包括在Fky中的常用工具函数
     */
    var f  = win['Fky'] ={};
    if (!win.F) {
        win['F'] = f;
    }
    /**
     * @name F.version
     * @function
     * @description  返回版本信息，创建时间，修改时间等
     * @return {Object}
     */
    f.version = function() {
        return {
            ver:0.43,
            createtime:'Thu Nov 17 2011 10:22:47 GMT+0800',
            ModificationDate:'Thu Dec 01 2011 11:10:39 GMT+0800'
        }
    };
    /**
     * @name F.config
     * @object
     * @description 配置一些选项
     * @version 0.1
     * @example
     *  {
     *      //是否打印错误
     *      debug:true
     *  }
     */
    f.config = {
        debug:true
    };
    /**
     * @name F.log
     * @function
     *@description  用控制台或alert打印日志
     */
    f.log = function() {
        if (!f.config.debug) {
            return ;
        }
        var s = '';
        s = Array.prototype.join.call(arguments, ' ');
        window.console ? console.log(s) : alert(s);
    };
    /**
     * @name F.type
     * @function
     * @description  判断变量类型
     * @version 0.3
     * @param o 需验证的变量
     * @param  {String} type 判断类型 number,string,boolean,array,regexp,function,null,undefined,object
     * @return {Boolean}
     */
    f.type = function(o, type) {
        var _t;
        return type === ((_t = typeof(o)) == "object" ?
                o == null && "null" || Object.prototype.toString.call(o).slice(8, -1) :
                _t
                ).toLowerCase();
    };
    /**
     * @name F.ready
     * @function
     * @description    dom 就绪
     * @version  0.8
     * @param  {Function} fn(f) 参数(f)
     * @retrun
     */
    f.ready = function() {
        var isReady = false,
            //函数列表
            readyList = [],
            //触发事件函数
            _fire;


        if ('addEventListener' in doc) {
            //w3c
             _fire = function() {
                doc.removeEventListener('DOMContentLoaded', _fire, false);
                _fireReady();
            };
            doc.addEventListener('DOMContentLoaded', _fire, false);
        } else {
            //  <= ie8
             _fire = function() {
                doc.detachEvent('onreadystatechange', _fire);
                    if ( doc.readyState == 'complete') {
                        _fireReady();
                    }
             };
            doc.attachEvent('onreadystatechange', _fire);
            (function(){
                try{
                //doScroll 如果抛出异常，说明dom未就绪
                    doc.documentElement.doScroll('left');
                    _fireReady();
                }catch(e){
                    setTimeout(arguments.callee,10);
                }
            })();

            //win.attachEvent('onload',_fireReady);
        }
        /**
         * 触发所有绑定函数
         */
        function _fireReady() {
            if (isReady) {
                return;
            }
            isReady = true;
            // 如果有绑定的函数
            if (readyList.length>0) {
                //执行全部绑定的
                var fn, i = 0;
                while (fn = readyList[i++]) { 
                    fn.call(win, f);
                }
                //重置
                readyList = [];
            }
        }

        return function(fn) {
            if (!f.type(fn, 'function')) {
                return false;
            }
            if (isReady) {
                // Execute the function immediately
                fn.call(win, f);
            } else { 
                // Remember the function for later
                readyList.push(fn);
            }
        };
    }();
    /**
     * @name F.each
     * @function
     * @description 迭代数组或对象  默认执行环境window
     * @version 0.5
     * @param o 可迭代的对象或数组
     * @param fn(item,i,o)
     * @param {Object} ctx 执行环境
     */
    f.each = function(o, fn, ctx) {
        var i=0,
            length=o.length;
            //
            ctx = ctx || win;
        if (f.type(o, 'function') || f.type(o, 'object') && !o.item && !o.callee && !o.nodeName ) {
            for (var key in o) {
                fn.apply(ctx, [o[key],key,o]);
            }
        } else {
            //arguments,collection,elements,array的迭代
            for (; i < length; i++) {
                fn.apply(ctx, [o[i],i,o]);
            }
        }


    };
    /**
     * @name F.extend
     * @function
     * @description 实现继承，子类通过调用sub.parent调用父类
     * @version 0.1
     * @param {Function} sup 超类
     * @param {Function | Object} sub Function为子类 | Object子类覆盖/扩展的方法或属性
     * @param {Object | Boolean} o Object子类覆盖/扩展的方法或属性 | Boolean同第4个参数
     * @p {Boolean} true时，添加的属性/方法扩展到原型，false时，添加的属性/方法扩展到对象上
     */
    f.extend = function(sup, sub, o, p) {
               //
        if(!f.type(sup,'function')){
            f.log('f.extend第一个参数为function');
            return;
        }
        p = p || o || false;
        if(f.type(sub,'object')){
            if(p!==true){
                f.each(sub,function(v,k){
                     sup.prototype[k]=v;
                });
            }else{
                f.each(sub,function(v,k){
                     sup[k]=v;
                });
            }
            return ;
        }

        //拷贝原型
        sub.prototype = sup.prototype;
        //添加constructor属性，之前被覆盖
        sub.prototype.constructor = sub;
        //添加父类的引用
        sub.parent = sup;
        if (f.type(o, 'object')) {
            //添加属性或方法
            if(p!==true){
                f.each(o, function(v, k) {
                    sub.prototype[k] = v;
                });
            }else{
                f.each(o, function(v, k) {
                    sub[k] = v;
                });
            }
        }
    };
    /**
     * @name F.merge
     * @function
     * @description  合并数组或{}，如果第一个参数为数组，则返回数组，返回的数组不会替换前面的数组，如果要替换，
     * 第一个参数设置为ture。如果第一个参数为true，会执行深度拷贝。
     * @version 0.1
     * @param arg1
     * @param arg2
     * @param arg3
     * @param ...
     * @return {Array | Object }
     */
    f.merge = function() {
        var result = {},
            i=0,
            length=arguments.length;
            arg = arguments,
            arg0=arg[0],
            deep = false,
            arr=false;
            //如果第一个参数为true ，循环从第二个参数开始
            if(arg0===true){
                deep=true;
                arg0=arg[1];
                i=1;
            }
            //如果第一个参数为数组，使返回的结果为数组，否则为object
            if(f.type(arg0,'array')){
                arr=true;
                result = [];
            }

            for(;i<length;i++){
                 _copy(arg[i],result);
            }
            function _copy(obj,r){
                f.each(obj,function(o,k){
                    //去掉item和length属性
                    if (k === 'item' || k === 'length') return;
                    //如果第一个参数是数组
                    if ( arr && ! deep) {
                        r.push(o);
                    } else {
                        //如果是深度拷贝
                        if( deep ){
                            //如果是数组
                            if( f.type(o,'array')){
                                r[k]=_copy(o,r[k]||[]);
                            }else if( f.type(o,'object') ){
                                //如果是对象
                                r[k]=_copy(o,r[k]||{});
                            }else{
                                r[k]=o;
                             }

                        }else{
                            r[k] = o;
                        }
                    }
                });
                return r;
            }
        return result;
    };
    /**
     * @name F.inarray
     * @function
     * @description  查看元素是否在数组中，存在则返回数组的索引，否则返回-1
     * @version 0.1
     * @param {Array} array
     * @param  elem
     * @return {Number}
     */
    f.inarray =function(array,elem){
        if ( array.indexOf ) {
			return array.indexOf( elem );
		}
		for ( var i = 0, length = array.length; i < length; i++ ) {
			if ( array[ i ] === elem ) {
				return i;
			}
		}
		return -1;
    };
    /**
     * @name F.filter
     * @function
     * @description  过滤数组或对象，根据fn的返回值，默认环境window
     * @version 0.1
     * @param o
     * @param fn(item,i,o)
     * @param ctx
     * @return {Object| Array}
     */
    f.filter=function(o,fn,ctx){
        var newo=[];
        ctx=ctx||win;
        if('filter' in o){
            newo=o.filter(fn,ctx);
        }else if (f.type(o, 'object') && !o.item && !o.callee && !o.nodeName ) {
            newo={};
            f.each(o,function(v,i,o){
                if(fn.call(ctx,v,i,o)){
                   newo[i]=v;
                }
            });
        }else{
            f.each(o,function(v,i,o){
                if(fn.call(ctx,v,i,o)){
                   newo.push(v);
                }
            });
        }
        return newo;
    };
    /**
     * @name F.trim
     * @function
     * @description  去掉字符串首尾空格，换行等
     * @version 0.1
     * @param {String} str
     * @return {String}
     */
    f.trim=function(str){
        var s='', retrim = /^\s+|\s+$/g;
        if(!f.type(str,'string')){
            f.log('F.trim 参数不是字符串'); return s;
        }
        if(str.trim){
            s=str.trim();
        }else{
            s=str.replace(retrim,'');
        }
        return s;
    }
})();
